package site.xuxingcan;


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import site.xuxingcan.Model.*;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

/**
 * Created by xuxingcan on 16-6-27.
 */
public class FileHelper {
    private static FileHelper instance;
    private Gson gson;
    private ArrayList<UserModel> userModelList;
    private BaseSettingModel settingModel;
    private ArrayList<YazhuModel> rightYazhuModels = new ArrayList<>();

    public ArrayList<UserModel> getUserModelList() {
        return userModelList;
    }

    public static FileHelper getInstance() {
        if (instance == null) {
            synchronized (FileHelper.class) {
                if (instance == null) {
                    instance = new FileHelper();
                }
            }
        }
        return instance;
    }

    public FileHelper() {
        gson = new Gson();

        try {
            userModelList = gson.fromJson(readUserData(),
                    new TypeToken<ArrayList<UserModel>>() {
                    }.getType());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (userModelList == null) {
            userModelList = new ArrayList<>();
        }

        try {
            settingModel = gson.fromJson(readSetting(), BaseSettingModel.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (settingModel == null) {
            settingModel = new BaseSettingModel();
        }
    }

    public UserModel getBankerUserModel() {
        for (UserModel model : userModelList) {
            if (model.isBanker) {
                return model;
            }
        }
        return null;
    }

    public UserModel findUserByName(String name) {
        for (UserModel model : userModelList) {
            if (model.userName.equalsIgnoreCase(name)) {
                return model;
            }
        }
        return null;
    }

    public long getStartTime(ArrayList<HongBaoModel> list) {
        long time = Long.MAX_VALUE;
        for (HongBaoModel hongBaoModel : list) {
            if (hongBaoModel.time < time) {
                time = hongBaoModel.time;
            }
        }
        return time;
    }

    public long getEndTime(ArrayList<HongBaoModel> list) {
        long time = Long.MIN_VALUE;
        for (HongBaoModel hongBaoModel : list) {
            if (hongBaoModel.time > time) {
                time = hongBaoModel.time;
            }
        }
        return time;
    }

    public StringModel computeHongBaoResult(ArrayList<HongBaoModel> hongBaoModelArrayList) {
        try {
            long startTime = getStartTime(hongBaoModelArrayList);
            long overTime = startTime + settingModel.overtime;
            long endTime = getEndTime(hongBaoModelArrayList);
            HongBaoModel bankerHongBaoModel = null;
            UserModel bankerUserModel = getBankerUserModel();
            if (bankerUserModel == null) {
                StringModel stringModel = new StringModel();
                stringModel.string = "没有庄家";
                return stringModel;
            }
            int bankerOrginIntegral = bankerUserModel.userIntegral;
            for (HongBaoModel hongBaoModel : hongBaoModelArrayList) {
                int yazhuIntegral = getUserYazhuIntegral(hongBaoModel.userName);
                if (yazhuIntegral >= 0) {
                    hongBaoModel.yazhuIntegral = yazhuIntegral;
                    hongBaoModel.isBanker = false;
                    hongBaoModel.info = HongBaoModel.OK;
                    if (hongBaoModel.time <= overTime) {
                        hongBaoModel.rate = getRate(hongBaoModel.money);
                    } else {
                        hongBaoModel.rate = -1;
                    }
                } else if (hongBaoModel.userName.equalsIgnoreCase(bankerUserModel.userName)) {
                    hongBaoModel.isBanker = true;
                    hongBaoModel.info = HongBaoModel.OK;
                    if (hongBaoModel.time <= overTime) {
                        hongBaoModel.rate = getRate(hongBaoModel.money);
                    } else {
                        hongBaoModel.rate = -1;
                    }
                    bankerHongBaoModel = hongBaoModel;
                } else {
                    hongBaoModel.info = HongBaoModel.NOT_YAZHU;
                }
            }
            if (bankerHongBaoModel == null) {
                StringModel stringModel = new StringModel();
                stringModel.string = "庄家无包，此局作废！";
                return stringModel;
//                bankerHongBaoModel = new HongBaoModel();
//                bankerHongBaoModel.userName = bankerName;
//                bankerHongBaoModel.rate = -1;
//                bankerHongBaoModel.money = -1;
//                bankerHongBaoModel.isBanker = true;
            }
            for (HongBaoModel hongBaoModel : hongBaoModelArrayList) {
                if (!hongBaoModel.isBanker && hongBaoModel.info.equalsIgnoreCase(HongBaoModel.OK)) {
                    if (hongBaoModel.rate < bankerHongBaoModel.rate) {
                        hongBaoModel.info = HongBaoModel.LOSE;
                    } else if (hongBaoModel.rate == bankerHongBaoModel.rate) {
                        if (hongBaoModel.money <= bankerHongBaoModel.money) {
                            hongBaoModel.info = HongBaoModel.LOSE;
                        } else {
                            hongBaoModel.info = HongBaoModel.WIN;
                        }
                    } else {
                        hongBaoModel.info = HongBaoModel.WIN;
                    }
                }
            }
            ArrayList<HongBaoModel> loseList = new ArrayList<>();
            ArrayList<HongBaoModel> winList = new ArrayList<>();
            ArrayList<HongBaoModel> notList = new ArrayList<>();
            for (HongBaoModel hongBaoModel : hongBaoModelArrayList) {
                if (hongBaoModel.isBanker) {
                    continue;
                }
                if (hongBaoModel.info.equalsIgnoreCase(HongBaoModel.LOSE)) {
                    loseList.add(hongBaoModel);
                } else if (hongBaoModel.info.equalsIgnoreCase(HongBaoModel.WIN)) {
                    winList.add(hongBaoModel);
                } else if (hongBaoModel.info.equalsIgnoreCase(HongBaoModel.NOT_YAZHU)) {
                    notList.add(hongBaoModel);
                }
            }
            Collections.sort(loseList);
            Collections.sort(winList);
            Collections.sort(notList);
            String lose = "--------以下老板输------\n";
            for (HongBaoModel hongBaoModel : loseList) {
                hongBaoModel.resultIntegral = bankerHongBaoModel.rate * hongBaoModel.yazhuIntegral;
                UserModel userModel = getUserModelByName(hongBaoModel.userName);
                userModel.userIntegral -= hongBaoModel.resultIntegral;
                bankerUserModel.userIntegral += hongBaoModel.resultIntegral;
                lose += hongBaoModel.userName + "    " + hongBaoModel.yazhuIntegral + "    " + bankerHongBaoModel.rate + "    输" + hongBaoModel.resultIntegral + "    余" + userModel.userIntegral + "\n";
            }
            bankerUserModel.userIntegral -= settingModel.hongbaoqian;
            if (bankerUserModel.userIntegral < 0) {
                bankerUserModel.userIntegral = 0;
            }
            String win = "--------以下老板赢------\n";
            for (HongBaoModel hongBaoModel : winList) {
                hongBaoModel.resultIntegral = hongBaoModel.rate * hongBaoModel.yazhuIntegral;
                UserModel userModel = getUserModelByName(hongBaoModel.userName);
                if (bankerUserModel.userIntegral <= 0) {
                    win += hongBaoModel.userName + "    " + hongBaoModel.yazhuIntegral + "    牛" + hongBaoModel.rate + "    喝水    余" + userModel.userIntegral + "\n";
                } else {
                    if (bankerUserModel.userIntegral < hongBaoModel.resultIntegral) {
                        bankerUserModel.userIntegral = 0;
                        win += hongBaoModel.userName + "    " + hongBaoModel.yazhuIntegral + "    牛" + hongBaoModel.rate + "    喝水    余" + userModel.userIntegral + "\n";
                    } else {
                        userModel.userIntegral += hongBaoModel.resultIntegral;
                        bankerUserModel.userIntegral -= hongBaoModel.resultIntegral;
                        win += hongBaoModel.userName + "    " + hongBaoModel.yazhuIntegral + "    牛" + hongBaoModel.rate + "    赢" + hongBaoModel.resultIntegral + "    余" + userModel.userIntegral + "\n";
                    }
                }
            }
            String not_yazhu = "--------以下无注抢包------\n";
            for (HongBaoModel hongBaoModel : notList) {
                hongBaoModel.resultIntegral = settingModel.qianghongbao;
                UserModel userModel = findUserByName(hongBaoModel.userName);
                if (userModel != null) {
                    userModel.userIntegral -= settingModel.qianghongbao;
                    not_yazhu += hongBaoModel.userName + "    扣" + hongBaoModel.resultIntegral + "    余下积分:" + userModel.userIntegral + "\n";
                } else {
                    not_yazhu += hongBaoModel.userName + "\n";
                }
            }
            int choushui = 0;
            int bankerResultIntegral = bankerUserModel.userIntegral - bankerOrginIntegral;
            if (bankerResultIntegral > 0) {
                choushui = (int) (bankerResultIntegral * settingModel.choushuiRate);
            }
            String banker = "------庄家榜------\n";
            banker += "本局庄家：" + bankerHongBaoModel.userName + "\n";
            banker += "庄家抢包：" + bankerHongBaoModel.money + "\n";
            banker += "庄家倍率：" + bankerHongBaoModel.rate + "\n";
            banker += "庄家输赢：" + "赔" + winList.size() + "家    " + "吃" + loseList.size() + "家" + "\n";
            banker += "上局剩余积分：" + bankerOrginIntegral + "\n";
            banker += "本局情况：" + bankerResultIntegral + "\n";
            banker += "群管理费：" + choushui + "\n";
            banker += "本局包费：" + settingModel.hongbaoqian + "\n";
            bankerUserModel.userIntegral -= choushui;
            banker += "本局剩余积分：" + bankerUserModel.userIntegral + "\n";
            String time = "-----------------------\n首包时间：" + time2Date(startTime) + "\n超时时间：" + time2Date(overTime) + "\n尾包时间：" + time2Date(endTime) + "\n";
            StringModel stringModel = new StringModel();
            stringModel.string = not_yazhu + win + lose + time + banker;
            writeUserData(gson.toJson(userModelList));
            return stringModel;
        } catch (Exception e) {
            StringModel stringModel = new StringModel();
            stringModel.string = "运算错误";
            return stringModel;
        }
    }

    private String time2Date(long time) {
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
            Date curDate = new Date(time);
            return formatter.format(curDate);
        } catch (Exception e) {
            return "NONE";
        }
    }

    public UserModel getUserModelByName(String name) {
        for (UserModel model : userModelList) {
            if (model.userName.equalsIgnoreCase(name)) {
                return model;
            }
        }
        return null;
    }

    public int getRate(float money1) {
        int money = (int) (money1 * 100);
        int n1 = money % 10;
        int n2 = money % 100 / 10;
        int n3 = money % 1000 / 100;
        if (n1 == 0 && n3 == 0) {
            return 11;
        } else if (n2 == n1 && n2 != 0) {
            return 12;
        } else if (n3 != 0 && n3 == n2 - 1 && n2 == n1 - 1) {
            return 13;
        } else if (n2 == 0 && n1 == 0) {
            return 14;
        } else if (n1 == n2 && n2 == n3) {
            return 15;
        } else {
            return (n1 + n2 + n3) % 10;
        }
    }

    public int getUserYazhuIntegral(String name) {
        for (YazhuModel yazhuModel : rightYazhuModels) {
            if (yazhuModel.userName.equalsIgnoreCase(name)) {
                return yazhuModel.yazhuIntegral;
            }
        }
        return -1;
    }

    public StringModel computeYazhuUsers(ArrayList<YazhuModel> yazhuModelArrayList) {
        String msg = "------下注信息------\n";
        rightYazhuModels.clear();
        for (YazhuModel yazhuModel : yazhuModelArrayList) {
            UserModel userModel = findUserByName(yazhuModel.userName);
            if (userModel == null) {
                yazhuModel.info = YazhuModel.NO_USER;
                msg += yazhuModel.userName + "    无分\n";
            } else if (yazhuModel.yazhuIntegral > userModel.userIntegral * settingModel.yazhuRate) {
                yazhuModel.info = YazhuModel.NOT_ENOUGH_INTEGRAL;
                yazhuModel.yazhuIntegral = (int) (userModel.userIntegral * settingModel.yazhuRate);
                rightYazhuModels.add(yazhuModel);
                msg += yazhuModel.userName + "    积分超限    认" + yazhuModel.yazhuIntegral + "\n";
            } else {
                yazhuModel.info = YazhuModel.OK;
                rightYazhuModels.add(yazhuModel);
            }
        }
        msg += "---------------------\n有效下注" + rightYazhuModels.size() + "人\n全体禁言，包手准备！";
        StringModel stringModel = new StringModel();
        stringModel.string = msg;
        return stringModel;
    }

    public void updateUser(UserModel model) {
        if (model.isBanker) {
            for (UserModel userModel : userModelList) {
                userModel.isBanker = false;
            }
        }
        boolean isNew = true;
        for (UserModel userModel : userModelList) {
            if (userModel.userName.equalsIgnoreCase(model.userName)) {
                userModel.userIntegral = model.userIntegral;
                userModel.isBanker = model.isBanker;
                isNew = false;
                break;
            }
        }
        if (isNew) {
            userModelList.add(model);
        }
        String json = gson.toJson(userModelList);
        try {
            writeUserData(json);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void writeSetting(String s) throws IOException {
        synchronized (this) {
            FileWriter writer = new FileWriter("Setting", false);
            writer.write(s);
            writer.flush();
            writer.close();
        }
    }

    public String readSetting() throws IOException {
        synchronized (this) {
            BufferedReader bufferedReader = new BufferedReader(new FileReader("Setting"));
            String temp = bufferedReader.readLine();
            StringBuffer sb = new StringBuffer();
            while (temp != null) {
                if (!temp.endsWith("\n")) {
                    temp += "\n";
                }
                sb.append(temp);
                temp = bufferedReader.readLine();
            }
            bufferedReader.close();
            return sb.toString();
        }
    }

    public void writeUserData(String s) throws IOException {
        synchronized (this) {
            FileWriter writer = new FileWriter("user.txt", false);
            writer.write(s);
            writer.flush();
            writer.close();
        }
    }

    public String readUserData() throws IOException {
        synchronized (this) {
            BufferedReader bufferedReader = new BufferedReader(new FileReader("user.txt"));
            String temp = bufferedReader.readLine();
            StringBuffer sb = new StringBuffer();
            while (temp != null) {
                if (!temp.endsWith("\n")) {
                    temp += "\n";
                }
                sb.append(temp);
                temp = bufferedReader.readLine();
            }
            bufferedReader.close();
            return sb.toString();
        }
    }
}
